package com.credithc.customers.manager.echarts;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.abel533.echarts.Grid;
import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.Title;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.*;
import com.github.abel533.echarts.series.Bar;
import com.github.abel533.echarts.series.Line;
import com.github.abel533.echarts.series.Pie;
import com.github.abel533.echarts.series.Series;
import com.github.abel533.echarts.style.AreaStyle;
import com.github.abel533.echarts.style.TextStyle;
import org.apache.commons.lang.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhukai
 */
public class EChartsCommon {

    protected List<String> rowList;
    protected List<String> columnList;
    protected Map<String, Integer> rowMap;
    protected Map<String, Integer> columnMap;
    protected int[][] dataArr;
    protected Option graph;

    public EChartsCommon() {
    }

    public EChartsCommon(List<String> rowList, List<String> columnList) {
        init(rowList, columnList);
    }

    private void init(List<String> rowList, List<String> columnList) {
        this.rowList = rowList;
        this.columnList = columnList;
        rowMap = new HashMap<String, Integer>();
        columnMap = new HashMap<String, Integer>();
        for (int i = 0; i < rowList.size(); i++) {
            rowMap.put(rowList.get(i), i);
        }
        for (int i = 0; i < columnList.size(); i++) {
            columnMap.put(columnList.get(i), i);
        }
        dataArr = new int[rowMap.size()][columnMap.size()];
        for (int i = 0; i < rowList.size(); i++) {
            for (int j = 0; j < columnList.size(); j++) {
                dataArr[i][j] = 0;
            }
        }
    }

    protected void setValue(String rowName, String colName, int val) {
        Integer row = rowMap.get(rowName), col = columnMap.get(colName);
        if (row != null && col != null) {
            dataArr[rowMap.get(rowName)][columnMap.get(colName)] = val;
        }
    }

    public void setValue(String colName, int val) {
        Integer col = columnMap.get(colName);
        if (col != null) {
            dataArr[0][columnMap.get(colName)] = val;
        }
    }

    private void setValue(int row, int col, int val) {
        dataArr[row][col] = val;
    }

    public void addValue(int row, int col, int val) {
        dataArr[row][col] += val;
    }

    public int getValue(int row, int col) {
        return dataArr[row][col];
    }

    protected EChartsCommon createGraph(String title, String subtitle) {
        graph = new Option();
        Title gTitle = graph.title();
        if (StringUtils.isNotBlank(title)) {
            gTitle.text(title).left("center");
        }
        if (StringUtils.isNotBlank(subtitle)) {
            gTitle.subtext(subtitle).subtextStyle(new TextStyle().fontSize(14));
        }
        graph.tooltip().trigger(Trigger.axis).axisPointer().type(PointerType.shadow);
        return this;
    }

    private Grid newGrid(int top, int left, int right, int height) {
        Grid grid = new Grid();
        if (top >= 0) {
            grid.top(top);
        }
        if (left >= 0) {
            grid.left(left);
        }
        if (height > 0) {
            grid.height(height);
        }
        if (right > 0) {
            grid.right(right);
        }
        return grid;
    }

    EChartsCommon createGrid(int top, int left, int right, int height) {
        graph.grid(newGrid(top, left, right, height));
        return this;
    }

    private CategoryAxis newCategoryAxis(int gridIndex, String name, List<String> xAxisList) {
        CategoryAxis axis = new CategoryAxis();
        axis.gridIndex(gridIndex);
        if (StringUtils.isNotBlank(name)) {
            axis.name(name);
        }
        for (String v : xAxisList) {
            axis.data(v);
        }
        return axis;
    }

    private ValueAxis newValueAxis(int gridIndex, String name, Object min, Object max) {
        ValueAxis axis = new ValueAxis();
        axis.gridIndex(gridIndex);
        if (StringUtils.isNotBlank(name)) {
            axis.name(name);
        }
        if (min != null) {
            axis.min(min);
        }
        if (max != null) {
            axis.max(max);
        }
        return axis;
    }

    protected EChartsCommon createCategoryXAxis(List<String> xAxisList, boolean show, boolean showLabel) {
        CategoryAxis axis = newCategoryAxis(0, null, xAxisList);
        axis.show(show).axisLabel().show(showLabel);
        graph.xAxis(axis);
        return this;
    }

    protected EChartsCommon createValueYAxis(String name, Object min, Object max, boolean show) {
        graph.yAxis(newValueAxis(0, name, min, max).show(show));
        return this;
    }

    protected EChartsCommon createLeftLegend(List<String> legendList, int top, int left,Orient orient) {
        graph.legend().data(legendList).orient(orient).left(left).top(top);
        return this;
    }

    protected EChartsCommon createRightLegend(List<String> legendList, int top, int right,Orient orient) {
        graph.legend().data(legendList).orient(orient).right(right).top(top);
        return this;
    }
    protected EChartsCommon createBottomLegend(List<String> legendList) {
        graph.legend().data(legendList).x(X.center).y(Y.bottom);
        return this;
    }

    protected EChartsCommon createBars(String stackName, boolean showLabel) {
        for (int i = 0; i < dataArr.length; i++) {
            createBar(i, stackName, showLabel);
        }
        return this;
    }

    private EChartsCommon createBar(int index, String stackName, boolean showLabel) {
        Bar bar = new Bar();
        bar.name(rowList.get(index)).type(SeriesType.bar);
        if (showLabel) {
            bar.label().normal().show(true).position(Position.top);
        }
        if (StringUtils.isNotBlank(stackName)) {
            bar.stack(stackName);
        }
        for (int j = 0; j < dataArr[index].length; j++) {
            bar.data(dataArr[index][j]);
        }
        graph.series(bar);
        return this;
    }

    private Line newLine(int xAxis, int yAxis, String name, LineType linetype, double data[]) {
        Line line = new Line();
        line.name(name).type(SeriesType.line).showAllSymbol(true).legendHoverLink(false).itemStyle().normal().lineStyle().type(linetype);
        line.xAxisIndex(xAxis).yAxisIndex(yAxis);
        for (double val : data) {
            line.data(val);
        }
        return line;
    }

    protected EChartsCommon createLine(String name, LineType linetype, double data[]) {
        Line line = newLine(0, 0, name, linetype, data);
        graph.series(line);
        return this;
    }

    protected EChartsCommon createLine(boolean showLabel,boolean smooth) {
        for (int i = 0; i < dataArr.length; i++) {
            Line line = new Line();
            line.name(rowList.get(i)).type(SeriesType.line);
            if (showLabel) {
                line.label().normal().show(true).position(Position.top);
            }
            for (int j = 0; j < dataArr[i].length; j++) {
                line.data(dataArr[i][j]);
            }
            line.setSmooth(smooth);
            line.areaStyle(new AreaStyle());
            graph.series(line);
        }
        return this;
    }

    protected EChartsCommon createSingleBar(boolean showLabel) {
        Bar bar = new Bar();
        bar.name(rowList.get(0)).type(SeriesType.bar);
        if (showLabel) {
            bar.label().normal().show(true).position(Position.top);
        }
        for (int j = 0; j < dataArr[0].length; j++) {
            bar.data(dataArr[0][j]);
        }
        graph.series(bar);
        return this;
    }

    protected EChartsCommon createPie(String name,String radius,String width,String height ){
        Pie pie = new Pie();
        pie.name(name).type(SeriesType.pie).radius(radius).center(width,height);
        pie.tooltip().trigger(Trigger.item).formatter("{a} <br/>{b} : {c} ({d}%)");
        for (int j = 0; j < dataArr[0].length; j++) {
            pie.data(generatePieData(dataArr[0][j],columnList.get(j)));
        }
        graph.series(pie);
        return this;
    }

    protected EChartsCommon setPieType(RoseType type){
        List<Series> series = graph.getSeries();
        Pie pie = (Pie) series.get(0);
        pie.setRoseType(type);
        return this;
    }

    protected EChartsCommon createInsideLabel(){
        List<Series> series = graph.getSeries();
        Pie pie = (Pie) series.get(0);
        pie.label().normal().formatter("{b}\n{c}({d}%)").position(Position.inside);
        return this;
    }

    protected EChartsCommon createOutsideLabel(){
        List<Series> series = graph.getSeries();
        Pie pie = (Pie) series.get(0);
        pie.label().normal().formatter("{b}\n{c}({d}%)").position(Position.outside);
        return this;
    }

    private JSONObject generatePieData(int value,String name){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("value",value);
        jsonObject.put("name",name);
        return jsonObject;
    }

    protected String toJSONString() {
        return JSON.toJSONString(graph);
    }

}